package top.honlnk.czuan.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.honlnk.czuan.common.constant.MorphemeTypeConstant;
import top.honlnk.czuan.common.constant.RelationTypeConstant;
import top.honlnk.czuan.common.constant.WordsTableIsAloneOptionConstant;
import top.honlnk.czuan.common.context.UserContextHolder;
import top.honlnk.czuan.common.exception.CustomException;
import top.honlnk.czuan.common.utils.SnowflakeIdUtil;
import top.honlnk.czuan.mapper.AddMapper;
import top.honlnk.czuan.mapper.get.GetTranslationMapper;
import top.honlnk.czuan.pojo.dto.add.AddMorphemeDTO;
import top.honlnk.czuan.pojo.dto.add.AddRelationDTO;
import top.honlnk.czuan.pojo.dto.add.AddTranslationDTO;
import top.honlnk.czuan.pojo.dto.add.AddWordDTO;
import top.honlnk.czuan.pojo.entity.Translations;
import top.honlnk.czuan.pojo.entity.User;
import top.honlnk.czuan.pojo.entity.Words;
import top.honlnk.czuan.pojo.vo.GetTranslationVO;
import top.honlnk.czuan.service.AddService;
import top.honlnk.czuan.service.impl.module.add.AddMorphemeSIModule;
import top.honlnk.czuan.service.impl.module.add.AddRelationSIModule;
import top.honlnk.czuan.service.impl.module.add.AddWordSIModule;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;


@Slf4j
@Service
public class AddServiceImpl implements AddService {

    @Autowired
    private AddMapper addMapper;

    @Autowired
    private SnowflakeIdUtil snowflakeIdUtil;

    @Autowired
    private AddMorphemeSIModule addMorphemeSIModule;

    @Autowired
    private AddWordSIModule addWordSIModule;

    @Autowired
    private AddRelationSIModule addRelationSIModule;

    @Autowired
    private GetTranslationMapper getTranslationMapper;

    // 获取当前用户的账号
    private String getUserAccount() {
        User currentUser = UserContextHolder.getUser();
        return currentUser.getAccount();
    }

    // 生成唯一id值
    private Integer makeOnlyId() {
        return snowflakeIdUtil.nextId();
    }

    @Override
    public Integer addTranslation(@NotNull AddTranslationDTO addTranslationDTO) {

        List<Translations> translations = new ArrayList<>();

        Translations translation = Translations.builder()
                .id(makeOnlyId())
                .translation(addTranslationDTO.getTranslation())
                .partId(addTranslationDTO.getPartSpeechId())
                .createdBy(getUserAccount())
                .updateBy(getUserAccount())
                .build();
        log.info("translations = {}", translation);
        translations.add(translation);

        addMapper.addTranslations(translations);

        return translations.get(0).getId();
    }

    @Override
    public Map<String, Map<Integer, String>> addTranslationAll(List<AddTranslationDTO> addTranslationDTOList) {
        // 根据在数据库中查出已经有的addTranslationDTOList中的数据
        List<Translations> foundTranslationsList = getTranslationMapper.getTranslationInfoOfList(addTranslationDTOList);
        // 构建已存在的翻译标识符集合（translation + "-" + partId）
        Map<String, Translations> existingTranslationsMap = foundTranslationsList.stream()
                .collect(Collectors.toMap(
                        translations -> translations.getTranslation() + "-" + translations.getPartId(),
                        translations -> translations
                ));

        // 筛选出未找到的翻译
        List<AddTranslationDTO> noFoundTranslationList = addTranslationDTOList.stream()
                .filter(dto -> !existingTranslationsMap.containsKey(dto.getTranslation() + "-" + dto.getPartSpeechId()))
                .toList();

        // 获取已经存在的翻译id列表
        Set<Integer> oldTranslationIdSet = foundTranslationsList.stream()
                .map(Translations::getId)
                .collect(Collectors.toSet());

        // 将数据库中没有的数据批量插入到数据库中，并获取新插入的id列表
        List<Integer> newTranslationIdList = new ArrayList<>();
        List<Translations> translations = new ArrayList<>();
        for (AddTranslationDTO addTranslationDTO : noFoundTranslationList) {
            Integer id = makeOnlyId();
            Translations translation = Translations.builder()
                    .id(id)
                    .translation(addTranslationDTO.getTranslation())
                    .partId(addTranslationDTO.getPartSpeechId())
                    .createdBy(getUserAccount())
                    .updateBy(getUserAccount())
                    .build();
            newTranslationIdList.add(id);
            translations.add(translation);
        }
        if (!translations.isEmpty()) {
            addMapper.addTranslations(translations);
        }


        // 整合新旧id列表
        List<Integer> translationIdList = new ArrayList<>();
        translationIdList.addAll(oldTranslationIdSet);
        translationIdList.addAll(newTranslationIdList);
        // 根据这些id查询出所有的数据
        List<GetTranslationVO> translationsVOList = getTranslationMapper.getTranslationListInfo(translationIdList);

        // 将数据封装成map返回
        return translationsVOList.stream()
                .collect(Collectors.groupingBy(
                        GetTranslationVO::getPartSimple,
                        Collectors.toMap(
                                GetTranslationVO::getId,
                                GetTranslationVO::getTranslation
                        )
                ));
    }

    @Override
    public void addRelation(@NotNull String type, @NotNull AddRelationDTO addRelationDTO) {
        Integer formId = addRelationDTO.getFormId();
        Integer toId = addRelationDTO.getToId();
        // TODO 优化：现在的功能实现代码过于冗余，后期优化
        switch (type) {
            // 单词与根词关系
            case RelationTypeConstant.WORD_TO_ROOT:
                addRelationSIModule.addWordTORootRelation(formId, toId);
                break;
            // 单词与前缀关系
            case RelationTypeConstant.WORD_TO_PREFIX:
                addRelationSIModule.addWordToPrefixRelation(formId, toId);
                break;
            // 单词与后缀关系
            case RelationTypeConstant.WORD_TO_SUFFIX:
                addRelationSIModule.addWordToSuffixRelation(formId, toId);
                break;

            // 单词与翻译关系
            case RelationTypeConstant.WORD_TO_TRANSLATION:
                addRelationSIModule.addWordToTranslationRelation(formId, toId);
                break;

            // 词根与翻译关系
            case RelationTypeConstant.ROOT_TO_TRANSLATION:
                addRelationSIModule.addRootToTranslationRelation(formId, toId);
                break;
            // 前缀与翻译关系
            case RelationTypeConstant.PREFIX_TO_TRANSLATION:
                addRelationSIModule.addPrefixToTranslationRelation(formId, toId);
                break;
            // 后缀与翻译关系
            case RelationTypeConstant.SUFFIX_TO_TRANSLATION:
                addRelationSIModule.addSuffixToTranslationRelation(formId, toId);
                break;

            default:
                throw new CustomException("关系参数不合法");
        }
    }

    @Override
    public void addWord(@NotNull AddWordDTO addWordDTO) {
        Words words = Words.builder()
                .id(makeOnlyId())
                .word(addWordDTO.getWord())
                .baseTranslation(addWordDTO.getBaseTranslation())
                .usSymbol(addWordDTO.getUsSymbol())
                .enSymbol(addWordDTO.getEnSymbol())
                .explain(addWordDTO.getExplain())
                .sense(addWordDTO.getSense())
                .superordinateId(addWordDTO.getSuperordinateId())

                .translationsIdList(addWordSIModule.getPartAndTIdListJson(addWordDTO.getTranslationIdList()))

                .rootsIdList(addWordDTO.getRootIdListJson())
                .prefixesIdList(addWordDTO.getPrefixIdListJson())
                .suffixesIdList(addWordDTO.getSuffixIdListJson())

                .rootsTranslationsIdList(addWordSIModule.getRTIdListJson(addWordDTO.getRootIdList()))
                .prefixesTranslationsIdList(addWordSIModule.getPFTIdListJson(addWordDTO.getPrefixIdList()))
                .suffixesTranslationsIdList(addWordSIModule.getSFTIdListJson(addWordDTO.getSuffixIdList()))

                .dictDataJsonUrl(addWordDTO.getDictDataJsonUrl())
                .aiExplainMdUrl(addWordDTO.getAiExplainMdUrl())
                .enAudioUrl(addWordDTO.getEnAudioUrl())
                .zhAudioUrl(addWordDTO.getZhAudioUrl())

                .createdBy(getUserAccount())
                .updateBy(getUserAccount())
                .build();
        log.info("words = {}", words);
        addMapper.addWord(words);

        // 创建单词与翻译的关系
        addWordDTO.getTranslationIdList().forEach(translationId -> addWordSIModule.addTranslation(words.getId(), translationId));
        // 创建单词与根词的关系
        addWordDTO.getRootIdList().forEach(rootId -> addWordSIModule.addRoot(words.getId(), rootId));
        // 创建单词与前缀词的关系
        addWordDTO.getPrefixIdList().forEach(prefixId -> addWordSIModule.addPrefix(words.getId(), prefixId));
        // 创建单词与后缀词的关系
        addWordDTO.getSuffixIdList().forEach(suffixId -> addWordSIModule.addSuffix(words.getId(), suffixId));
    }

    @Override
    public void addMorpheme(@NotNull String type, AddMorphemeDTO addMorphemeDTO) {
        // TODO 优化：现在的功能实现代码过于冗余，后期优化
        switch (type) {
            case MorphemeTypeConstant.ROOT:
                log.info("词根；addMorphemeDTO: {}", addMorphemeDTO);
                addMorphemeSIModule.addRoot(addMorphemeDTO, getUserAccount(), makeOnlyId());
                break;
            case MorphemeTypeConstant.PREFIX:
                log.info("前缀；addMorphemeDTO: {}", addMorphemeDTO);
                addMorphemeSIModule.addPrefix(addMorphemeDTO, getUserAccount(), makeOnlyId());
                break;
            case MorphemeTypeConstant.SUFFIX:
                log.info("后缀；addMorphemeDTO: {}", addMorphemeDTO);
                addMorphemeSIModule.addSuffix(addMorphemeDTO, getUserAccount(), makeOnlyId());
                break;
            default:
                throw new CustomException("词素参数不合法");
        }
        if (addMorphemeDTO.getFormId() != null) {
            addMapper.updateWordsIsAlone(addMorphemeDTO.getFormId(), WordsTableIsAloneOptionConstant.NOT_ALONE, getUserAccount());
        }

    }
}
